# 函数可以调用其他函数
def story():
    print("用户故事")
    return "小白兔吃萝卜"

def tell():
    s = story()
    return s + "带上好健康一起吃"
# print(tell())# 调用并且打印这个函数
"""
用户故事
小白兔吃萝卜带上好健康一起吃
"""
# 自己调用自己，但是没有出口
def tell_story():
    print("从前有座山")
    print("山上有座庙")
    print("庙里有个老健康")
    print("在给小健康讲故事")
    tell_story() # 自己调用自己

# tell_story()

# 递归需要注意：
"""
1、必须要有出口
"""
# 案例1 计算从x开始到10内的和
def text1(i):
    if i == 10:
        return 10
    else:
        return i + text1(i+1)
# r = text1(1)
# print(r) # 1+2+3+4+5+6+7+8+9+10
# 每次递归后，都会开辟一个栈帧空间，直到达到结果，触底反弹
# 案例2 计算x整数以内的和
def sum2(x):
    if x > 1:
        value = x + sum2(x - 1)
    else:
        value = 1
    return value
# print(sum2(10)) # 55
# print(sum2)

# 匿名函数
# print(lambda x, y: x + y) # 返回的是地址值
# print(lambda x, y: x + y())
# print(lambda x, y: x + y(1,2))

# 调用：匿名函数的精髓就是没有名字，为其绑定名字是没有意义的
# a = lambda x, y: x + y # 赋值一个名字，去调用
# print(a(1,2))

# 匿名函数和内置函数一起使用
salarics={
    'xiaolong3':30000,
    'xiaolong2':3000,
    'long1':1000,
}
# 比较一下薪资
# print(max(salarics))

# 这个函数需要获得字典的value，这样才会比较value

def func(name):
    """

    :param name: 通过这个方法，来获取每一个value值
    :return:
    """
    return salarics[name]
# print(max(salarics,key=func)) # key是一个形参，用他的value去比对每一个键值
#
# # 转化成匿名函数
# max(salarics, key=lambda name:salarics[name])
#
# # 求最小值：匿名函数
# print(min(salarics,key=lambda name:salarics[name]))

# 闭包函数
def outer():
    print("外面的函数正在运行")
    def inner():
        print("里面的函数正在运行")
    return inner # 欠它一个()
# inner = outer() # 此时 inner == inner,没有调用
# inner() # 调用
# outer()() # 这样补上去也可以，但是不建议这么用
"""
外面的函数正在运行
里面的函数正在运行
"""

# 案例3
def aa():
    a = 10 # 外函数定义了一个10
    def bb():
        # a = 100
        nonlocal a # todo:修改函数内的变量值
        a = 99
        print(f"内函数{a}")
        """
        局部变量>全局变量
        我想在局部变量里面，修改a的值
        """
    print(f"aa外函数{a}")
    def cc():
        print(f"cc函数的值是{a}")
    return bb(),cc()



    return bb()
# aa()
"""
外函数10
100

aa外函数10
内函数99
cc函数的值是99
"""


def a():
    print("我是a")
    def b():
        print("我是b")
        def c():
            print("我市c")
        c()
    b()
    print("lalala")
    print("我市健康")
    def e():
        print("我是e")
        def g():
            print("我市g")
    print("啦啦啦")
    e()
    def p():
        print("我市p")
    return p()
# a()
"""
我是a
我是b
我市c
lalala
我市健康
啦啦啦
我是e
我市p
"""

# 闭包案例：自增长函数--每次调用它的时候，自己 + 1
# def auto_num():
#     num = 0
#     def add():
#         nonlocal num
#         num += 1
#         return num
#     return add  # 外函数返回的是子函数的地址值，锁住地址值比较关键
# # print(auto_num()())
# # num = auto_num()
# # print(num())
# # print(num())
# # print(num())
# # print(num())
#
#
# def auto_num():
#     num = 0
#     def add():
#         nonlocal num
#         num += 1
#         return num
#     return add()  # 外函数返回的是子函数的地址值，锁住地址值比较关键
# # print(auto_num()())
# num = auto_num()
# print(num)
# # print(num())
# # print(num())
# # print(num())

# 装饰器 ：是一个特殊的闭包函数
"""def run():
    print("跑步")
# run()
# 还是run方法，我想加一个健身
def run():
    print("跑步")
    print("健身") # 这样子是不对的，相当于重写了一个方法;这个不是装饰器
run()
"""

'''
男孩1嫌弃女朋友丑 带女朋友去买衣服 项链和化妆品 变的更加自信 
原来的外貌 原来的性格 没有发生改变 :装饰器

男孩2嫌弃女朋友丑 带女朋友去整容 变的更加自信(万一失败呢？) 
原来的外貌 原来的性格发现改变 ： 不是装饰器
'''

"""name = "好健康"
def run(name):
    print("==========")
    print(f"我是:{name}")
    print("==========")
# run(name)

def decorate(func):
    def new_func(new_name):
        print("我市装饰器前面的代码")
        func(new_name)
        print("我是装饰器后面的代码")
    return new_func
new_func = decorate(run)
new_func("琳姐")
"""

# 装饰器案例1：自我介绍
"""def student_info(name):
    print("=============")
    print(f"大家好，我叫{name}")
    print("=============")

def info(func): # info() 函数是为了修饰括号里面的函数；func参数，是函数参数，func替你要装饰的函数占位置，然后不加括号是因为加上之后会调用函数
    def luoji(name,address,phone,mmadd,sex):
        func(name)  # 其实就是 student_info(name) 在这里，func()就是代替student_info()的
        print(f"我的家庭地址是在：{address},我的手机号:{phone}，我的新地址{mmadd},我的性别是{sex}")
        print("自我介绍完毕")
    return luoji
s = info(student_info)  # 这个student_info 是实际你要修饰的函数，
s("好健康","辽宁沈阳","213234234","吉林","男")"""

# 案例2 时间装饰器模块
from datetime import datetime # 时间处理模块

n = 900000
def for1(n):
    sum = 0
    for i in range(1,n+1):
        sum += i
    print(sum)
def run_time(func):
    def new_func(n):
        start_time = datetime.now()
        print(f"开始时间：{start_time}")
        func(n)
        end_time = datetime.now()
        print(f"结束时间：{end_time}")
        time1 = end_time - start_time
        print(f"花费时间是：{time1}")
    return new_func
# for1 = run_time(for1)
# for1(n)
"""
开始时间：2025-03-31 17:21:27.293087
405000450000
结束时间：2025-03-31 17:21:27.371035
花费时间是：0:00:00.077948
"""

# 简化装饰器


def run_time1(func):
    def new_func(n):
        start_time = datetime.now()
        print(f"开始时间：{start_time}")
        func(n)
        end_time = datetime.now()
        print(f"结束时间：{end_time}")
        time1 = end_time - start_time
        print(f"花费时间是：{time1}")
    return new_func
n1 = 900000